home *** CD-ROM | disk | FTP | other *** search
- Path: xanth!mcnc!rutgers!tut.cis.ohio-state.edu!cwjcc!hal!ncoast!allbery
- From: george@rebel.UUCP (George M. Sipe)
- Newsgroups: comp.sources.misc
- Subject: v04i120: make any command screen oriented
- Message-ID: <48343@rebel.UUCP>
- Date: 11 Oct 88 02:20:38 GMT
- Sender: allbery@ncoast.UUCP
- Reply-To: george@rebel.UUCP (George M. Sipe)
- Organization: Tolerant Systems, Atlanta GA
- Lines: 500
- Approved: allbery@ncoast.UUCP
-
- Posting-number: Volume 4, Issue 120
- Submitted-by: "George M. Sipe" <george@rebel.UUCP>
- Archive-name: vis
-
- #! /bin/sh
- # This is a shell archive, meaning:
- # 1. Remove everything above the #! /bin/sh line.
- # 2. Save the resulting text in a file.
- # 3. Execute the file with /bin/sh (not csh) to create:
- # README
- # Makefile
- # vis.man
- # vis.c
- # This archive created: Fri Jul 22 14:37:25 1988
- export PATH; PATH=/bin:/usr/bin:$PATH
- if test -f 'README'
- then
- echo shar: "will not over-write existing file 'README'"
- else
- sed 's/^X//' << \SHAR_EOF > 'README'
- XVis repeatedly executes a specified command and refreshes the display
- Xof its output on the screen. This has the effect of making any
- Xnormally non-screen oriented command into a screen oriented one.
- X
- XThe first line on the output screen is reserved for vis status and will
- Xcontain the command on the left side with the current execution count
- Xon the right side. If command is too long to fit, vis will truncate it
- Xin the status line and append an ellipsis ("...").
- X
- XThe output of the command normally begins on the third line and
- Xcontinues to the end of the screen. Lines which can not fit will be
- Xdiscarded. When this occurs, vis will automatically place the output
- Xof following passes starting on line two in order to maximize the
- Xamount of displayed information.
- X
- XSee the manual page for a complete information.
- X
- X
- X Copyright (c) 1988 by George M. Sipe. All rights reserved.
- X
- XThis software may only be redistributed without fee and without any
- Xother form of monetary gain (including sold, rented, leased, or
- Xtraded), unless the express written permission of the copyright holder
- Xis obtained in advance.
- X
- XThis copyright notice must be reproduced in its entirety on all copies
- Xof this software. Further, acknowledgment of the authorship of this
- Xsoftware must not be removed from its current or derived
- Xdocumentation.
- X
- XNo expressed or implied warranty is made for this software. No party
- Xconnected with this software assumes any liability or responsibility
- Xfor its use, the correctness of its operation, or its fitness for any
- Xpurpose.
- X
- XAny distributor of copies of this software shall grant the recipient
- Xpermission for further redistribution as permitted by this notice.
- X
- XPermission is hereby granted to copy, reproduce, redistribute and
- Xotherwise use this software as long as the conditions above are
- Xstrictly adhered to.
- X
- XNOTE: This software was originally written by Dan Heller
- X (argv@sri-spam.arpa) and enhanced / generalized by
- X George M. Sipe (rebel!george) to the point where Dan
- X would no longer recoginze it. No copyright notices
- X were embodied in the original net distribution.
- SHAR_EOF
- fi
- if test -f 'Makefile'
- then
- echo shar: "will not over-write existing file 'Makefile'"
- else
- sed 's/^X//' << \SHAR_EOF > 'Makefile'
- X# Makefile for: vis - repeatedly run command, refreshing screen
- X
- XDEFINES = -DBSD
- XCFLAGS = -O $(DEFINES)
- XLIBS = -lcurses -ltermcap
- XROFF = nroff
- XRFLAGS = -man
- XLDFLAGS = -s
- XDESTBIN = ${HOME}
- XDESTMAN = ${HOME}
- XDESTCAT = ${HOME}
- XDESTOWN = root
- XDESTGRP = staff
- XSHELL = /bin/sh
- XMAKEFILE = Makefile
- XPROGRAM = vis
- XMANPAGES = vis.man
- XCATPAGES = vis.cat
- XSRCS = vis.c
- XOBJS = vis.o
- X
- X.man.cat:
- X $(ROFF) $(RFLAGS) $< > $@
- X
- X.SUFFIXES: .man .cat
- X
- X# Compile and load the program and format its manual pages.
- Xall: $(PROGRAM) $(CATPAGES)
- X
- X$(PROGRAM): $(OBJS)
- X $(CC) $(LDFLAGS) $(OBJS) $(LIBS) -o $(PROGRAM)
- X
- X# Run lint on source files, put results on standard output.
- Xlint:
- X lint -u $(DEFINES) $(SRCS)
- X
- X# Create a tags file for use by a source code editor.
- Xtags: $(SRCS)
- X ctags $(SRCS)
- X
- X# Edit the makefile and regenerate the dependency information.
- Xdepend:
- X mkmf -f $(MAKEFILE) PROGRAM=$(PROGRAM) DESTBIN=$(DESTBIN)
- X
- X# Print an index of functions on standard output.
- Xindex:
- X ctags -wx $(SRCS)
- X
- X# Print source code files on standard output.
- Xprint:
- X lpr -p $(SRCS) $(MANPAGES)
- X
- X# Compile and load the program, format manual pages, and move them
- X# to their destination directories.
- Xinstall: $(PROGRAM) $(CATPAGES)
- X cp $(PROGRAM) $(DESTBIN)
- X chmod 755 $(DESTBIN)/$(PROGRAM)
- X chown $(DESTOWN) $(DESTBIN)/$(PROGRAM)
- X chgrp $(DESTGRP) $(DESTBIN)/$(PROGRAM)
- X -for manpage in $(MANPAGES); do \
- X basepage=`basename $$manpage .man`; \
- X cp $$basepage.man $(DESTMAN)/$$basepage.l; \
- X chmod 644 $(DESTMAN)/$$basepage.l; \
- X chown $(DESTOWN) $(DESTMAN)/$$basepage.l; \
- X chgrp $(DESTGRP) $(DESTMAN)/$$basepage.l; \
- X cp $$basepage.cat $(DESTCAT)/$$basepage.l; \
- X chmod 644 $(DESTCAT)/$$basepage.l; \
- X chown $(DESTOWN) $(DESTCAT)/$$basepage.l; \
- X chgrp $(DESTGRP) $(DESTCAT)/$$basepage.l; \
- X done
- X
- X# Remove the program and its formatted manual pages from their
- X# destination directories.
- Xuninstall:
- X rm -f $(DESTBIN)/$(PROGRAM)
- X -for manpage in $(MANPAGES); do \
- X basepage=`basename $$manpage .man`; \
- X rm -f $(DESTMAN)/$$basepage.l; \
- X rm -f $(DESTCAT)/$$basepage.l; \
- X done
- X
- X# Remove all target and intermediate files.
- Xclean:
- X -rm -f $(PROGRAM) $(CATPAGES) $(OBJS)
- X -rm -f core a.out made *.o
- SHAR_EOF
- fi
- if test -f 'vis.man'
- then
- echo shar: "will not over-write existing file 'vis.man'"
- else
- sed 's/^X//' << \SHAR_EOF > 'vis.man'
- X.TH VIS l "21 July 1988"
- X.SH NAME
- Xvis \- repeatedly run command, refreshing screen
- X.SH SYNTAX
- X.B vis "[-d delay] [-f] command [args]"
- X.SH DESCRIPTION
- X.I Vis
- Xrepeatedly executes a specified
- X.B command
- Xand refreshes the display of its output on the screen. This has the
- Xeffect of making any normally non-screen oriented command into a screen
- Xoriented one.
- X.PP
- X.B Command
- Xmay represent multiple commands by enclosing them in quotes and
- Xseparating them by ``;''. Similarly, commands may be piped together by
- Xenclosing them in quotes and separating them by ``|''. The single or
- Xdouble quotes around such a compound command are necessary to escape
- Xprocessing from the shell.
- X.PP
- XThe first line on the output screen is reserved for
- X.I vis
- Xstatus and will contain the
- X.B command
- Xon the left side with the current execution count on the right side. If
- X.B command
- Xis too long to fit,
- X.I vis
- Xwill truncate it in the status line and append an ellipsis ("...").
- X.PP
- XThe output of the command normally begins on the third line and
- Xcontinues to the end of the screen. Lines which can not fit will be
- Xdiscarded. When this occurs,
- X.I vis
- Xwill automatically place the output of following passes starting on line
- Xtwo in order to maximize the amount of displayed information.
- X.PP
- XThe following switches may be specified if desired:
- X.TP 10
- X.B "-d delay"
- Xspecifies a non-default delay of
- X.B delay
- Xseconds. Normally
- X.I vis
- Xwill delay for 15 seconds between command re-executions. If a
- Xnon-default delay is specified, the
- X.I vis
- Xstatus line will also include the delay interval centered within it
- X(unless that would cause it to overwrite a long command, in which case
- Xit will be centered between the end of the command and the execution
- Xcount).
- X.TP
- X.B -f
- X.I Vis
- Xwill automatically terminate if
- X.B command
- Xreturns a non-zero status. The
- X.B -f
- Xflag forces
- X.I vis
- Xto continue. When
- X.B -f
- Xis specified,
- X.I vis
- Xwill not terminate and will instead precede the execution count in the
- X.I vis
- Xstatus line by a ``!'' flag whenever a non-zero status has been returned
- Xby
- X.B command .
- X.SH EXAMPLES
- Xvis ps
- X.IP "" 5
- XContinually display the status of processes on the system (up to 23
- Xlines).
- X.PP
- Xvis -d 60 'who ; echo ""; df'
- X.IP "" 5
- XDisplay the system users and disk usage statistics every 60 seconds.
- XSeparate the two with a blank line.
- X.SH "SEE ALSO"
- XUser Commands (1): sh, csh
- X.SH DIAGNOSTICS
- XIf
- X.B command
- Xreturns a non-zero status and
- X.B -f
- Xhas not been specified to
- X.I vis ,
- X.I vis
- Xwill terminate and return that status.
- X.SH AUTHOR
- XOriginally written by Dan Heller (argv@sri-spam.arpa).
- X.PP
- XIt has been substantially enhanced and generalized by George M. Sipe
- X(currently - 7/88, at rebel!george) to the point where Dan would no
- Xlonger recognize it.
- SHAR_EOF
- fi
- if test -f 'vis.c'
- then
- echo shar: "will not over-write existing file 'vis.c'"
- else
- sed 's/^X//' << \SHAR_EOF > 'vis.c'
- X/* Copyright (c) 1988 by George M. Sipe. All rights reserved.
- X
- XThis software may only be redistributed without fee and without any
- Xother form of monetary gain (including sold, rented, leased, or
- Xtraded), unless the express written permission of the copyright holder
- Xis obtained in advance.
- X
- XThis copyright notice must be reproduced in its entirety on all copies
- Xof this software. Further, acknowledgment of the authorship of this
- Xsoftware must not be removed from its current or derived
- Xdocumentation.
- X
- XNo expressed or implied warranty is made for this software. No party
- Xconnected with this software assumes any liability or responsibility
- Xfor its use, the correctness of its operation, or its fitness for any
- Xpurpose.
- X
- XAny distributor of copies of this software shall grant the recipient
- Xpermission for further redistribution as permitted by this notice.
- X
- XPermission is hereby granted to copy, reproduce, redistribute and
- Xotherwise use this software as long as the conditions above are
- Xstrictly adhered to.
- X
- X NOTE: This software was originally written by Dan Heller
- X (argv@sri-spam.arpa) and enhanced / generalized by George M.
- X Sipe (rebel!george) to the point where Dan would no longer
- X recoginze it. No copyright notices were embodied in the
- X original net distribution.
- X*/
- X
- X#include <stdio.h>
- X#include <curses.h>
- X#include <signal.h>
- X#include <sys/types.h>
- X
- X#ifndef DELAY
- X#define DELAY 15 /* default delay, if not otherwise set */
- X#endif DELAY
- X#ifndef BASELINE
- X#define BASELINE 2 /* default line number for output */
- X#endif BASELINE
- X
- X#define max(a,b) (a < b ? b : a)
- X#define equal(str1,str2) !strcmp(str1, str2)
- X
- X#define pinput fildes[0]
- X#define poutput fildes[1]
- X
- X#ifdef BSD
- X#include <sys/wait.h>
- Xextern char *index();
- Xextern time_t time();
- Xextern int exit();
- Xextern int _exit();
- Xextern int perror();
- Xextern int sleep();
- X#else
- Xunion wait {
- X int w_status;
- X};
- X#define vfork() fork() /* fork on non-BSD */
- X#define dup2(from,to) close(to); (void) dup(from) /* good enough here */
- X#define index(str,chr) strchr(str,chr) /* strchr on non-BSD */
- Xextern char *strchr();
- Xextern long time();
- Xextern void exit();
- Xextern void _exit();
- Xextern void perror();
- Xextern unsigned int sleep();
- X#endif BSD
- X
- Xextern int optind;
- Xextern char *optarg;
- X
- Xlong wait_delay = DELAY; /* delay interval */
- Xint force = 0; /* true to force continued execution */
- Xint needshell = 0; /* non-zero if subshell needed */
- X
- X/* create command line string for display */
- Xstatic char *command(argc, argv)
- Xint argc;
- Xchar **argv;
- X{
- X static char string[255];
- X int count = 0;
- X char *cp = string;
- X
- X do {
- X (void) sprintf(cp, "%s ", argv[count]);
- X cp += strlen(cp);
- X needshell |= (int) index(argv[count], '|');
- X needshell |= (int) index(argv[count], ';');
- X } while (++count < argc);
- X *--cp = '\000';
- X return (string);
- X}
- X
- X/* all done, cleanup and exit */
- Xstatic int terminate(cause)
- X{
- X#ifdef BSD
- X (void) sigsetmask(-1);
- X#endif
- X move(LINES - 1, 0);
- X clrtoeol();
- X echo();
- X refresh();
- X endwin();
- X exit(cause);
- X}
- X
- Xint main(argc, argv)
- Xint argc;
- Xchar **argv;
- X{
- X register int curline;
- X register int iteration = 0;
- X register int c;
- X int sw;
- X int badsw = 0;
- X int baseline = BASELINE;
- X long nextcycle;
- X long curtime;
- X long delta;
- X int fildes[2];
- X int pid;
- X union wait status;
- X char *cmd = argv[0];
- X char *shcmd[4];
- X FILE *fp;
- X
- X (void) signal(SIGQUIT, terminate); /* exit when requested */
- X (void) signal(SIGINT, terminate); /* exit when requested */
- X (void) signal(SIGPIPE, SIG_IGN); /* when output > screen size */
- X
- X while ((sw = getopt (argc, argv, "d:f")) != EOF)
- X switch (sw) {
- X case 'f':
- X force = !force;
- X break;
- X case 'd':
- X wait_delay = atoi(optarg);
- X if (wait_delay < 1) wait_delay = 1;
- X break;
- X case '?':
- X default:
- X badsw = 1;
- X break;
- X }
- X argv = &argv[optind];
- X argc -= optind;
- X if (badsw || argc < 1) {
- X (void) fprintf(stderr,
- X "Usage: %s [-d delay] [-f] command [args]\n", cmd);
- X exit (-1);
- X }
- X initscr();
- X cmd = command(argc, argv);
- X if (needshell != 0) {
- X shcmd[0] = "sh";
- X shcmd[1] = "-c";
- X shcmd[2] = cmd;
- X shcmd[3] = (char *) 0;
- X }
- X if (wait_delay != DELAY) {
- X if (strlen(cmd) > COLS-39)
- X (void) sprintf(cmd, "%.*s...", COLS-42, cmd);
- X mvprintw(0, max((COLS-11)/2, strlen(cmd)+15), "Delay: %d",
- X wait_delay);
- X } else if (strlen(cmd) > COLS-21)
- X (void) sprintf(cmd, "%.*s...", COLS-24, cmd);
- X mvprintw(0, 0, "Command: %s", cmd);
- X noecho(); /* don't let typing ruin our painting */
- X nextcycle = time(0) + wait_delay;
- X while (1) {
- X mvprintw(0, COLS - 10, "Exec: %d", ++iteration);
- X if (iteration == 1) refresh();
- X (void) pipe(fildes);
- X /* fork and exec redirecting stdout thru pipe to curses */
- X if (!(pid = vfork())) {
- X (void) dup2(poutput, 1);
- X (void) dup2(poutput, 2);
- X (void) close(pinput);
- X if (needshell == 0) (void) execvp(*argv, argv);
- X else (void) execv("/bin/sh", shcmd);
- X perror(*argv);
- X _exit(-1);
- X }
- X if (pid == -1) terminate(-2);
- X if (!(fp = fdopen(pinput, "r"))) terminate(-3);
- X (void) close(poutput);
- X curline = baseline;
- X move(curline, 0);
- X /* read the command's output */
- X while ((c = getc(fp)) != EOF && !ferror(fp) && curline < LINES)
- X if (c == '\n') {
- X clrtoeol();
- X move(++curline, 0);
- X }
- X else addch(c);
- X if (ferror(fp)) terminate(-4);
- X if (baseline > 1 && curline == LINES && c != EOF)
- X --baseline;
- X /* we've found the end of file, thus, the end of exec */
- X (void) fclose(fp);
- X clrtobot();
- X move(LINES - 1, 0);
- X refresh();
- X (void) wait(&status); /* wait for child to terminate */
- X /* if child didn't terminate properly, w_status will != 0 */
- X if (status.w_status) {
- X mvprintw(0, COLS - 12, "!");
- X if (!force) terminate(status.w_status);
- X }
- X curtime = time(0);
- X delta = nextcycle - curtime;
- X if (delta > 0) {
- X nextcycle = curtime + delta + wait_delay;
- X (void) sleep((unsigned) delta);
- X } else nextcycle = curtime + wait_delay;
- X }
- X}
- SHAR_EOF
- fi
- exit 0
- # End of shell archive
- --
- George M. Sipe, Phone: (404) 662-1533
- Tolerant Systems, 6961 Peachtree Industrial, Norcross, GA 30071
- UUCP: ...!{decvax,hplabs,linus,rutgers,seismo}!gatech!rebel!george
-